package org.xx.armory.security;

import org.xx.armory.commons.NameObjectBag;

import java.io.Serializable;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.Objects;

import static org.xx.armory.commons.Validators.notBlank;

/**
 * 用户。
 * <p>通过{@link org.xx.armory.commons.NameObject}的形式保存附加数据。只接收{@link String}, {@link Boolean}, {@link Integer}, {@link Long}和{@link java.math.BigDecimal}类型的附加数据。</p>
 *
 * @author Haart
 * @see #putString(String, String)
 * @see #putBoolean(String, boolean)
 * @see #putInteger(String, int)
 * @see #putLong(String, long)
 * @see #putDecimal(String, BigDecimal)
 */
public final class User
        extends NameObjectBag
        implements Serializable {
    /**
     *
     */
    private static final long serialVersionUID = 1L;

    private final String name;

    private final Date createDate;

    private final Date lastModifiedDate;

    private final boolean enabled;

    private final Collection<String> roles;

    /**
     * 创建字段都是空白的用户对象。
     */
    public User() {
        this(null, null, null, true, null, null);
    }

    /**
     * 创建用户对象。
     *
     * @param name
     *         用户的名字, 会被正规化。
     * @param createDate
     *         用户对象创建日期。
     * @param lastModifiedDate
     *         用户对象最后修改日期。
     * @param enabled
     *         是否启用。
     * @param roles
     *         用户关联的角色名称集合。
     * @param values
     *         用户的附加信息。
     * @throws IllegalArgumentException
     *         如果参数{@code name}是{@code null}或者只包含空白字符。
     */
    public User(
            String name,
            Date createDate,
            Date lastModifiedDate,
            boolean enabled,
            Collection<String> roles,
            NameObjectBag values
    ) {
        super(values);

        this.name = notBlank(name, "name").trim();
        this.createDate = createDate;
        this.lastModifiedDate = lastModifiedDate;
        this.enabled = enabled;
        this.roles = roles != null ? new ArrayList<>(roles) : new ArrayList<>();
    }

    /**
     * 获取用户名。
     *
     * @return 用户名。
     */
    public final String getName() {
        return this.name;
    }

    /**
     * 获取创建日期。
     *
     * @return 创建日期。
     */
    public final Date getCreateDate() {
        return this.createDate;
    }

    /**
     * 获取最后修改日期。
     *
     * @return 最后修改日期。
     */
    public final Date getLastModifiedDate() {
        return this.lastModifiedDate;
    }

    /**
     * 获取此用户关联的角色集合。
     *
     * @return 此用户关联的角色集合。
     */
    public final Collection<String> getRoles() {
        return Collections.unmodifiableCollection(this.roles);
    }

    /**
     * 判断用户是否可用。
     *
     * @return 用户是否可用。
     */
    public final boolean isEnabled() {
        return this.enabled;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void putEnum(
            String name,
            Enum<?> v
    ) {
        throw new UnsupportedOperationException();
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void putDate(
            String name,
            Date v
    ) {
        throw new UnsupportedOperationException();
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public int hashCode() {
        return this.name.hashCode();
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (obj == null) {
            return false;
        }
        if (obj.getClass() != this.getClass()) {
            return false;
        }
        final User other = (User) obj;
        return Objects.equals(this.name, other.name);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public String toString() {
        return "User {" + "name: " + this.name + "}";
    }
}
